﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Telerik.Web.Mvc;

namespace Presentation.Web.Admin.Controllers
{
    [HandleError]
    public class RoleController : Infrastructure.Crosscutting.NetFramework.Controllers.BaseController
    {
        Infrastructure.Crosscutting.Authorize.IRoleService roleService;

        Infrastructure.Crosscutting.Authorize.IRoleMenuService roleMenuService;

        Infrastructure.Crosscutting.Authorize.IMvcRolePermissionService rolePermissionService;

        Infrastructure.Crosscutting.Authorize.IMvcActionService actionService;

        Infrastructure.Crosscutting.Caches.ICacheService cacheService;

        public RoleController(Infrastructure.Crosscutting.NetFramework.IWorkContext work,
            Infrastructure.Crosscutting.Authorize.IRoleService role,
            Infrastructure.Crosscutting.Authorize.IRoleMenuService roleMenu,
            Infrastructure.Crosscutting.Authorize.IMvcRolePermissionService rolePermission,
            Infrastructure.Crosscutting.Authorize.IMvcActionService action,
            Infrastructure.Crosscutting.Caches.ICacheService cache)
            : base(work)
        {
            if (role == null)
            {
                throw new ArgumentNullException("roleService is null");
            }
            if (roleMenu == null)
            {
                throw new ArgumentNullException("roleMenuService is null");
            }
            if (rolePermission == null)
            {
                throw new ArgumentNullException("rolePermissionService is null");
            }
            if (action == null)
            {
                throw new ArgumentNullException("actionService is null");
            }
            if (cache == null)
            {
                throw new ArgumentNullException("cacheService is null");
            }
            roleService = role;
            roleMenuService = roleMenu;
            rolePermissionService = rolePermission;
            actionService = action;
            cacheService = cache;
        }

        #region role

        public ActionResult Index()
        {
            var model = this.GetRoleTrueState();
            var dto = model.ToDto();
            return View(dto);
        }

        [GridAction]
        public ActionResult AjaxIndex(string searchKey)
        {
            var data = this.GetRoleTrueState();
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.Name.Contains(searchKey));
            }
            var dto = data.ToDto();
            var model = new GridModel<Domain.Dto.RoleDto>
            {
                Data = dto,
                Total = dto.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult Delete(int id)
        {
            var model = roleService.Get(id);
            if (model != null && model.Id > 0)
            {
                roleService.DeleteTrue(model, this.WorkContext.CurrentUser);
            }
            var data = this.GetRoleTrueState();
            var dto = data.ToDto();
            return Json(dto, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult MulDelete(FormCollection del)
        {
            var res = false;
            var message = "";
            var selectedList = del.GetValues("selectRow");
            if (selectedList != null && selectedList.Count() > 0)
            {
                res = roleService.DeleteTrue(selectedList.ToIntList(), this.WorkContext.CurrentUser);
                message = res == true ? "" : "删除失败了，T_T";
            }
            //返回空，是为了不再请求数据，因为他自己会重新binding的
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [GridAction]
        [HttpPost]
        public JsonResult Add(Domain.Dto.RoleDto dto)
        {
            dto.AddTime = System.DateTime.Now;
            dto.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
            var entity = dto.ToEntity();
            roleService.Add(entity, this.WorkContext.CurrentUser);
            var data = this.GetRoleTrueState();
            var model = new GridModel<Domain.Dto.RoleDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult Edit(Domain.Dto.RoleDto dto)
        {
            if (dto.Id > 0)
            {
                var entity = roleService.Get(dto.Id);
                if (entity != null && entity.Id > 0)
                {
                    entity.Name = string.IsNullOrEmpty(dto.Name) ? "" : dto.Name.Trim();
                    entity.Remark = string.IsNullOrEmpty(dto.Remark) ? "" : dto.Remark.Trim();
                    entity.DefaultUrl = string.IsNullOrEmpty(dto.DefaultUrl) ? "/" : dto.DefaultUrl.Trim();
                    if (!string.IsNullOrEmpty(dto.DefaultUrl))
                    {
                        entity.DefaultUrl = dto.DefaultUrl.Trim();
                    }
                    roleService.Modify(entity, this.WorkContext.CurrentUser);
                }
            }
            var data = this.GetRoleTrueState();
            var model = new GridModel<Domain.Dto.RoleDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpGet]
        public JsonResult Search(string term)
        {
            if (!string.IsNullOrEmpty(term))
            {
                var data = this.GetRoleTrueState().Where(e => e.Name.Contains(term.Trim()))
                            .OrderBy(e => e.Id).Take(10)
                            .Select(e => e.Name).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
            else
            {
                var data = this.GetRoleTrueState().OrderBy(e => e.Id).Take(10)
                            .Select(e => e.Name).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #region role menu

        [HttpGet]
        public ViewResult Menu(int id)
        {
            var role = roleService.Get(id);
            ViewBag.role = role;
            var data = this.GetRoleMenuTrueState(id).ToDto();
            return View(data);
        }

        [GridAction]
        public JsonResult AjaxMenu(int id, int roleId)
        {
            var data = this.GetRoleMenuTrueState(roleId).ToDto();
            var model = new GridModel<Domain.Dto.RoleMenuDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpPost]
        public JsonResult AddMenu(Domain.Dto.RoleMenuDto dto)
        {
            var res = false;
            var message = "";
            if (!string.IsNullOrEmpty(dto.Name) && !string.IsNullOrEmpty(dto.Url) && dto.RoleId > 0)
            {
                dto.AddTime = System.DateTime.Now;
                dto.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                dto.State = true;
                var entity = dto.ToEntity();
                try
                {
                    roleMenuService.Add(entity, this.WorkContext.CurrentUser);
                    dto = entity.ToDto();
                    res = true;
                }
                catch (Exception ex)
                {
                    message = ex.Message;
                }
            }
            else
            {
                message = "请提交正确的数据";
            }
            return Json(new { success = res, message = message, data = dto }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        [GridAction]
        public JsonResult DeleteMenu(int id, int roleId)
        {
            var entity = roleMenuService.Get(id);
            if (entity != null)
            {
                roleMenuService.DeleteTrue(entity, this.WorkContext.CurrentUser);
            }
            var data = this.GetRoleMenuTrueState(roleId).ToDto();
            var model = new GridModel<Domain.Dto.RoleMenuDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpPost]
        [GridAction]
        public JsonResult EditMenu(Domain.Dto.RoleMenuDto dto, int roleId)
        {
            var entity = roleMenuService.Get(dto.Id);
            if (entity != null)
            {
                entity.CssName = dto.CssName;
                entity.Name = string.IsNullOrEmpty(dto.Name) ? "" : dto.Name.Trim();
                entity.ParentId = dto.ParentId;
                entity.Remark = string.IsNullOrEmpty(dto.Remark) ? "" : dto.Remark.Trim();
                entity.RoleId = dto.RoleId;
                entity.SortNum = dto.SortNum;
                entity.Url = dto.Url;
                entity.State = dto.State;
                roleMenuService.Modify(entity, this.WorkContext.CurrentUser);
            }
            var data = this.GetRoleMenuTrueState(roleId).ToDto();
            var model = new GridModel<Domain.Dto.RoleMenuDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        #endregion

        #region permission

        #region installed

        public ViewResult Permission(int? id)
        {
            var roleModel = roleService.Get(id ?? 0);
            ViewBag.rolemodel = roleModel;
            var data = rolePermissionService.GetRoleInstallPermissionByRoleId(id ?? 0);
            return View(data);
        }

        [GridAction]
        public JsonResult AjaxPermission(int? id, string searchKey, int? conId)
        {
            var data = rolePermissionService.GetRoleInstallPermissionByRoleId(id ?? 0);
            if (conId.HasValue && conId.Value > 0)
            {
                data = data.Where(e => e.ControllerId == conId.Value).ToList();
            }
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.ActionName.ToLower().Contains(searchKey.ToLower().Trim())).ToList();
            }
            var model = new GridModel<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult MulDeleteRolePermission(FormCollection mul)
        {
            var roleIdStr = mul["RoleId"];
            int roleId = 0;
            int.TryParse(roleIdStr, out roleId);
            var res = false;
            var message = "";
            if (roleId > 0)
            {
                var selecteList = mul.GetValues("selectRow");
                var deleteActionIdList = selecteList.ToIntList();

                var deleteIdList = rolePermissionService.GetList()
                    .Where(e => e.RoleId == roleId && deleteActionIdList.Contains(e.ActionId))
                    .Select(e => e.Id).ToList();

                res = rolePermissionService.DeleteTrue(deleteIdList, this.WorkContext.CurrentUser);
            }
            //返回空，是为了不再请求数据，因为他自己会重新binding的
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public JsonResult SearchInPermission(int? id, string term, int? conId)
        {
            var rolePermission = rolePermissionService.GetRoleInstallPermissionByRoleId(id ?? 0);
            if (conId.HasValue && conId.Value > 0)
            {
                rolePermission = rolePermission.Where(e => e.ControllerId == conId.Value).ToList();
            }
            if (!string.IsNullOrEmpty(term))
            {
                var data = rolePermission.Where(e => e.ActionName.ToLower().Contains(term.ToLower().Trim()))
                            .OrderBy(e => e.ActionId).Take(10)
                            .Select(e => e.ActionName).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
            else
            {
                var data = rolePermission.OrderBy(e => e.ActionId).Take(10)
                            .Select(e => e.ActionName).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #region uninstall

        public ViewResult AddPermission(int? id)
        {
            var roleModel = roleService.Get(id ?? 0);
            ViewBag.rolemodel = roleModel;
            var model = rolePermissionService.GetRoleUninstallPermissionByRoleId(id ?? 0);
            ViewBag.id = id;
            return View(model);
        }

        [GridAction]
        public JsonResult AjaxAddPermission(int? id, string searchKey, int? conId)
        {
            var data = rolePermissionService.GetRoleUninstallPermissionByRoleId(id ?? 0);
            if (conId.HasValue && conId.Value > 0)
            {
                data = data.Where(e => e.ControllerId == conId.Value).ToList();
            }
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.ActionName.ToLower().Contains(searchKey.ToLower().Trim()))
                    .OrderByDescending(e => e.ActionId).ToList();
            }
            var model = new GridModel<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult MulInstallRolePermission(FormCollection mul)
        {
            var roleIdStr = mul["RoleId"];
            int roleId = 0;
            int.TryParse(roleIdStr, out roleId);
            var res = false;
            var message = "";
            if (roleId > 0)
            {
                var selectedList = mul.GetValues("selectRow");
                var intSelectedList = selectedList.ToIntList();
                var actionList = actionService.GetList(selectedList.ToIntList().AsQueryable()).Where(e => e.State == true).ToList();
                foreach (var item in actionList)
                {
                    var temp = new Domain.Entity.MvcRolePermission();
                    temp.ActionId = item.Id;
                    temp.AddTime = System.DateTime.Now;
                    temp.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                    temp.Name = item.Name;
                    temp.Remark = item.Remark;
                    temp.RoleId = roleId;
                    temp.SortNum = 0;
                    temp.State = true;
                    rolePermissionService.Add(temp, this.WorkContext.CurrentUser);
                }
                res = true;
            }
            //返回空，是为了不再请求数据，因为他自己会重新binding的
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public JsonResult SearchUnPermission(int? id, string term, int? conId)
        {
            var model = rolePermissionService.GetRoleUninstallPermissionByRoleId(id ?? 0);
            if (conId.HasValue && conId.Value > 0)
            {
                model = model.Where(e => e.ControllerId == conId.Value).ToList();
            }
            if (!string.IsNullOrEmpty(term))
            {
                var data = model.Where(e => e.ActionName.ToLower().Contains(term.ToLower().Trim()))
                    .OrderByDescending(e => e.ActionId).Take(10)
                    .Select(e => e.ActionName).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
            else
            {
                var data = model.OrderByDescending(e => e.ActionId).Take(10)
                    .Select(e => e.ActionName).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #endregion

        #region util

        protected IQueryable<Domain.Entity.RoleMenu> GetRoleMenuTrueState(int id)
        {
            var data = roleMenuService.GetList().Where(e => e.RoleId == id);
            return data;
        }

        protected IQueryable<Domain.Entity.Role> GetRoleTrueState()
        {
            var data = roleService.GetList().Where(e => e.State == true)
                .OrderByDescending(e => e.Id);
            return data;
        }

        #endregion
    }
}
